<?php
//我的模块,请求失败(代码出现错误,写库失败等)时返回数据到前端,
function requestFailReturnBack($exception)
{
    switch ($exception->getCode()) {
        case 0:
            //返回系统繁忙
            $msg = '系统繁忙';
            break;
        case 500:
            //返回业务错误原因
            $msg = $exception->getMessage();
            break;
    }

    //返回给前端
    json([
        'code' => 0,
        'msg' => $msg,
        'error' => $exception->getMessage()
    ])->send();

    exit();

}

//异常时公共的返回
function errorBack($exception)
{


    //异常的状态码
    $code = $exception->getCode();

    //返回的数据
    switch ($code) {
        case 1:
            //手动抛出异常
            $msg = $exception->getMessage();
            break;
        case 1001:
            $msg = $exception->getMessage();
            break;
        case 1002:
            $msg = $exception->getMessage();
            break;
        default:
            $code = 0;
            $msg = '系统繁忙';
            break;
    }
    //返回给前端
    json([
        'code' => $code,
        'msg' => $msg,
        'error' => $exception->getMessage()
    ])->send();
    exit();
}

//请求成功时的公共返回
function successBack($data, $msg = '请求成功')
{
    $successBack['code'] = 1;
    $successBack['msg'] = $msg;

    if ($data) {
        $successBack['data'] = $data;
    }
    //返回给前端
    json($successBack)->send();
    exit();
}

use app\essayhandle\controller\Addessay;
use \Firebase\JWT\JWT;
use think\Exception;
use think\Queue;

//uid加密
function createUserToken($user_data)
{
    $key = 'abcdefghijklmnopqrstuvwxyz123456789'; //key
    $time = time(); //当前时间
    $token = [
        'iss' => '', //签发者 可选
        'aud' => '', //接收该JWT的一方，可选
        'iat' => $time, //签发时间
        'nbf' => $time, //(Not Before)：某个时间点后才能访问，比如设置time+30，表示当前时间30秒后才能使用
        'exp' => strtotime('+3 month'), //过期时间,这里设置三个月
        //保存自定义的数据
        'user_data' => $user_data
    ];
    return JWT::encode($token, $key); //输出Token
}

//user_token解密
function verification($jwt)
{
    $key = 'abcdefghijklmnopqrstuvwxyz123456789'; //key

    try {
        \Firebase\JWT\JWT::$leeway = 60;//当前时间减去60，把时间留点余地
        $decoded = \Firebase\JWT\JWT::decode($jwt, $key, ['HS256']); //HS256方式，这里要和签发的时候对应
        $arr = (array)$decoded;
        return $arr;
    } catch (\Firebase\JWT\SignatureInvalidException $e) {  //签名不正确
        throw new Exception($e->getMessage());
    } catch (\Firebase\JWT\BeforeValidException $e) {  // 签名在某个时间点之后才能用
        throw new Exception($e->getMessage());
    } catch (\Firebase\JWT\ExpiredException $e) {  // token过期
        throw new Exception('未登录', 1001);
    } catch (Exception $e) {  //其他错误
        throw new Exception($e->getMessage());
    }
    //Firebase定义了多个 throw new，我们可以捕获多个catch来定义问题，catch加入自己的业务，比如token过期可以用当前Token刷新一个新Token
}

//获取当前时间的毫秒数
function getMillisecond()
{
    list($s1, $s2) = explode(' ', microtime());
    return (float)sprintf('%.0f', (floatval($s1) + floatval($s2)) * 1000);
}

//计算发布时间距离当前时间有多久
function time_tran($the_time, $now_time)
{
    $show_time = $the_time;
    $dur = $now_time - $show_time;


    if ($dur < 60) {
        return $dur . '秒前';
    } else {
        if ($dur < 3600) {
            return floor($dur / 60) . '分钟前';
        } else {
            if ($dur < 86400) {
                return floor($dur / 3600) . '小时前';
            } else {
                if ($dur < 604800) {//7天内
                    return floor($dur / 86400) . '天前';
                } else {
                    return date('Y-m-d', $show_time);
                }
            }
        }
    }

}

//添加队列
//创建消息并推送到队列中
function add_queue($jobHandlerClassName, $jobQueueName, $jobData)
{

    // 1.当前任务将由哪个类来负责处理。
    //   当轮到该任务时，系统将生成一个该类的实例，并调用其 fire 方法(消费队列的类)
    //处理队列的地址命名空间
    //$jobHandlerClassName  = 'app\queueHandle\News';


    // 2.当前任务归属的队列名称，如果为新队列，会自动创建
    //$jobQueueName  	  = "feiyan_news";

    // 3.当前任务所需的业务数据 . 不能为 resource 类型，其他类型最终将转化为json形式的字符串
    //   ( jobData 为对象时，存储其public属性的键值对 )
    //$jobData       	  = [ 'ts' => time(), 'bizId' => uniqid() , 'a' => 100 ] ;

    // 4.将该任务推送到消息队列，等待对应的消费者去执行
    $isPushed = Queue::push($jobHandlerClassName, $jobData, $jobQueueName);

    // database 驱动时，返回值为 1|false  ;   redis 驱动时，返回值为 随机字符串|false
    if ($isPushed !== false) {
        return true;
        //echo date('Y-m-d H:i:s') . "插入到队列成功"."<br>";
    } else {
        return false;
        //echo '插入失败';
    }

}


//判断文章数据是否存在
function isNewsExist($item_id, $item_mongo_obj, $field = 'id')
{
    $news_result = $item_mongo_obj->where(['id' => $item_id])->field($field)->find();
    if (!$news_result) {
        throw new Exception('文章不存在');
    } else {
        return $news_result;
    }
}

//获取mongo库中某个集合，最新的计数，$name 表示筛选的 的条件
function getMid($name)
{

    //自增
    $update = array('$inc' => array("count" => 1));

    //自增条件
    $query = array('name' => $name);

    $cmd = [
        'findandmodify' => 'item_mid',//collection-name表名
        'update' => $update,//更新条件,把uid作为计数器,自增一个
        'query' => $query, //查询那个设置为计数器的集合
        'new' => true, //当true返回修改后的文档,而不是原始的。
        'upsert' => true//upsert: true选择update操作或更新一个匹配的文档,如果没有 匹配文档存在,创建一个新的文档:
    ];

    $Command = new \MongoDB\Driver\Command($cmd);
    $conn = new \MongoDB\Driver\Manager('mongodb://qizhijiaoyu:qizhijiaoyu_37099@yyblue.com:37099');
    $res = $conn->executeCommand('feiyan', $Command)->toArray();//TP5才用的方法
    return $res[0]->value->count;//这里返回了新的id
}

//获取智能推荐公共的代码
function getCommonAirecResult($scene_id, $user_type, $user_unique, $imei)
{
    //获取智能推荐的数据

    $addEssayObj = new Addessay();


    //获取智能推荐的参数
    $query = [];
    //场景id
    $query['sceneId'] = $scene_id;
    $query['ReturnCount'] = 5;
    switch ($user_type) {
        case 'login':
            $query['UserId'] = $user_unique;
            break;
        case 'not_login':
            $query['imei'] = $imei;
            break;
    }
    return $addEssayObj->getAirecResult($query);
}

//curl post 请求
function curl_post($url, $data = array())
{

    $ch = curl_init();

    curl_setopt($ch, CURLOPT_URL, $url);

    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);

    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);

    // POST数据
    curl_setopt($ch, CURLOPT_POST, 1);

    // 把post的变量加上
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);

    $output = curl_exec($ch);

    curl_close($ch);

    return json_decode($output, true);

}

//获取第几天签到的奖励
function getSignAward($day_number)
{
    $result = \think\Db::name('sign_conf')
        ->where(['day_number' => $day_number])
        ->field('feiyanbi_award,experience_award')
        ->find();

    return $result;
}